#ifndef COMMON_H
#define COMMON_H 

#include <stdint.h>

typedef struct {
    char name[50];
    uint64_t data;
    uint64_t value;
} PmuDataList;

typedef struct {
    int loop;
    int unroll;
    int core;
    int pmu_cnt;
    int run;
    int events_cnt;
    PmuDataList *events_list;
    char *binary_file;
} CodeConfig;

typedef struct {
    uint64_t evt_num : 8;
    uint64_t umask : 8;
    uint64_t user : 1;
    uint64_t os : 1;
    uint64_t edge : 1;
    uint64_t pc : 1;
    uint64_t api_int : 1;
    uint64_t any : 1;
    uint64_t enable : 1;
    uint64_t inv : 1;
    uint64_t cmask : 8;
} PmuConfig;

typedef enum { RDTSC, CYCLES, INSTRUCTIONS, FIX_PMU_EVENT_MAX } FIX_PMU_EVENT;

typedef union tagPmuData {
    uint64_t t64;
    uint32_t t32[2];
} PmuData;

#define READ_CORE_CYCLE(cycle)                      \
    __asm__ volatile("mov rcx, 0x40000001     \n\t" \
                     "lfence                  \n\t" \
                     "rdpmc                   \n\t" \
                     "lfence                  \n\t" \
                     : "=a"((cycle).t32[0]), "=d"((cycle).t32[1])::"rcx", "memory")

#endif // COMMON_H
